﻿
Imports std
Imports centrosphere

Partial Public Class storageJobDistributor
    Private Delegate Function int_compare_delegate(ByVal i As Int64, ByVal j As Int64) As Boolean
    Private Shared Function i64_compare_aggregate(ByVal targetJobs() As indexedJob,
                                                  ByVal inputJob As ijob,
                                                  ByVal compare As int_compare_delegate,
                                                  ByVal initValue As Int64,
                                                  ByVal setfailedValue As Boolean,
                                                  Optional ByVal failedValue As Int64 = npos) As Boolean
        aggregate_internal.assert_input(targetJobs, inputJob)
        assert(Not compare Is Nothing)
        Dim sj As storageJob = Nothing
        sj = storageJob(inputJob)
        sj.i64 = initValue
        sj.i64_2 = initValue
        For i As Int64 = 0 To targetJobs.Length() - 1
            If targetJobs(i).finished() Then
                Dim tj As storageJob = Nothing
                tj = storageJob(targetJobs(i))
                If tj.result Then
                    sj.result = True
                    If tj.i64 <> npos AndAlso compare(tj.i64, sj.i64) Then
                        sj.i64 = tj.i64
                    End If
                    If tj.i64_2 <> npos AndAlso compare(tj.i64_2, sj.i64_2) Then
                        sj.i64_2 = tj.i64_2
                    End If
                ElseIf setfailedValue Then
                    sj.i64 = failedValue
                    sj.i64_2 = failedValue
                End If
            End If
        Next

        Return True
    End Function

    Protected Shared Function i64_max_aggregate(ByVal targetJobs() As indexedJob,
                                                ByVal inputJob As ijob) As Boolean
        Return i64_compare_aggregate(targetJobs, inputJob, Function(i, j) i > j, 0, False)
    End Function

    Protected Shared Function i64_min_aggregate(ByVal targetJobs() As indexedJob,
                                                ByVal inputJob As ijob) As Boolean
        Return i64_compare_aggregate(targetJobs, inputJob, Function(i, j) i < j, maxInt64, True, 0)
    End Function

    Protected Shared Function i64_sum_aggregate(ByVal targetJobs() As indexedJob,
                                                ByVal inputJob As ijob) As Boolean
        aggregate_internal.assert_input(targetJobs, inputJob)
        Dim sj As storageJob = Nothing
        sj = storageJob(inputJob)
        For i As Int64 = 0 To targetJobs.Length() - 1
            If targetJobs(i).finished() Then
                Dim tj As storageJob = Nothing
                tj = storageJob(targetJobs(i))
                If tj.result Then
                    sj.result = True
                    sj.i64 += tj.i64
                    sj.i64_2 += tj.i64_2
                Else
                    Return inputJob.copy(targetJobs(i))
                End If
            End If
        Next

        Return True
    End Function

    Protected Function i64_redundance_divide_aggregate(ByVal targetJobs() As indexedJob,
                                                       ByVal inputJob As ijob) As Boolean
        assert(Not redundance_count Is Nothing)
        If i64_sum_aggregate(targetJobs, inputJob) Then
            Dim sj As storageJob = Nothing
            sj = storageJob(inputJob)
            If sj.result Then
                sj.i64 \= redundance_count()
                sj.i64_2 \= redundance_count()
            End If
            Return True
        Else
            Return False
        End If
    End Function
End Class
